package com.xu.ai.chatclient.controller;

import java.util.List;
import java.util.Map;

import org.springframework.ai.document.Document;
import org.springframework.ai.reader.TextReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.ai.vectorstore.filter.Filter;
import org.springframework.ai.vectorstore.filter.FilterExpressionBuilder;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

/**
 * MariaDB Vector 是 MariaDB 11.7 的一部分，支持存储和搜索机器学习生成的嵌入。
 * 它利用向量索引提供了高效的向量相似性搜索能力，支持余弦相似度和欧几里得距离度量。
 *
 * @author xuguan
 * @since 2025/9/18
 */
@RestController
@RequestMapping("/api/vector")
public class VectorStoreController {

	private final VectorStore vectorStore;

	public VectorStoreController(VectorStore vectorStore) {
		this.vectorStore = vectorStore;
	}

	@PostMapping(path = "/add")
	public void addVector() {
		Document document1 = new Document("Mike是一名Java开发工程师, 目前正在学习spring ai和spring ai alibaba",
				Map.of("name", "Mike", "job", "Java开发工程师", "learning", "spring ai和spring ai alibaba"));
		Document document2 = new Document("Mike喜欢写代码", Map.of("name", "Mike", "like", "coding"));
		Document document3 = new Document("Mike喜欢吃饺子", Map.of("name", "Mike", "like", "dumplings"));
		vectorStore.add(List.of(document1, document2, document3));
	}

	@PostMapping(path = "/upload")
	public void uploadVector(@RequestParam("data") MultipartFile data) {
		TextReader reader = new TextReader(data.getResource());
		final List<Document> documents = TokenTextSplitter.builder().build().split(reader.read());
		vectorStore.add(documents);
	}

	@GetMapping("/search")
	public List<Document> search(@RequestParam("name") String query) {
		return vectorStore.similaritySearch(SearchRequest.builder().query(query).topK(3).build());
	}

	@DeleteMapping("/delete-by-id")
	public void deleteById(@RequestParam("id") List<String> id) {
		vectorStore.delete(id);
	}

	@DeleteMapping("delete-by-filter")
	public void deleteByFilter(@RequestParam("name") String name) {
		FilterExpressionBuilder b = new FilterExpressionBuilder();
		Filter.Expression expression = b.eq("name", name).build();
		vectorStore.delete(expression);
	}

}
